package com.xiaoyang.billiards.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoyang.billiards.architecture.common.Errors.TableError;
import com.xiaoyang.billiards.architecture.common.exception.ServiceException;
import com.xiaoyang.billiards.architecture.utils.CheckUtil;
import com.xiaoyang.billiards.entity.PoolTable;
import com.xiaoyang.billiards.entity.Zone;
import com.xiaoyang.billiards.enums.TableEnums;
import com.xiaoyang.billiards.mapper.TableMapper;
import com.xiaoyang.billiards.params.TableParam;
import com.xiaoyang.billiards.response.TableResponse;
import com.xiaoyang.billiards.response.ZoneResponse;
import com.xiaoyang.billiards.service.TableService;
import com.xiaoyang.billiards.service.ZoneService;
import com.xiaoyang.billiards.transfer.TableTransfer;
import com.xiaoyang.billiards.transfer.ZoneTransfer;
import jakarta.annotation.Resource;
import org.apache.tomcat.jni.Pool;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.ls.LSInput;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @AUTHOR XiaoYang
 * @DATE 2024/3/3
 * @DESCRIPTION TODO
 */
@Service
public class TableServiceImpl extends ServiceImpl<TableMapper, PoolTable> implements TableService {

    @Resource
    private ZoneService zoneService;

    @Resource
    private TableMapper tableMapper;

    @Override
    public List<TableResponse> query(TableParam tableParam) {
        if (ObjectUtils.isEmpty(tableParam)){
            List<PoolTable> tableList = tableMapper.selectList(null);
            List<ZoneResponse> zoneResponseList = zoneService.query(null);
            //根据zoneId将两个集合变成TableResponse集合
            // 一个zone对应多个table
            List<TableResponse> tableResponses = TableTransfer.INSTANCE.transfer(zoneResponseList);
            // 将tableList根据zoneId分组
            Map<Integer, List<PoolTable>> zoneidTableMap = tableList.stream().collect(Collectors.groupingBy(PoolTable::getZoneId));
            tableResponses.forEach(tableResponse -> {
                if (zoneidTableMap.containsKey(tableResponse.getZoneId())) {
                    tableResponse.setTableInfo(zoneidTableMap.get(tableResponse.getZoneId()));
                }
            });
            return tableResponses;
        }
        return null;
    }

    @Override
    public Integer add(TableParam tableParam) {
        PoolTable poolTable = new PoolTable();
        poolTable.setZoneId(tableParam.getZoneId());
        poolTable.setState(TableEnums.ADD_STATE.getCode());
        try {
            return tableMapper.insert(poolTable);
        } catch (Exception e) {
            throw new ServiceException(TableError.ADD_ERROR,e.getMessage());
        }
    }

    @Override
    public Integer delete(TableParam tableParam) {
        LambdaQueryWrapper<PoolTable> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CheckUtil.assertNotEmpty(tableParam.getTableId(),"删除的tableId为空"),PoolTable::getTableId,tableParam.getTableId());
        try {
            return tableMapper.delete(wrapper);
        } catch (Exception e) {
            throw new ServiceException(TableError.DELETE_ERROR,e.getMessage().contains("FOREIGN KEY") ? "消费记录尚未删除" : e.getMessage());
        }
    }

    @Override
    public Integer start(TableParam tableParam) {
        // update pool_table set state = ?,start_time = now() where table_id = ?
        LambdaUpdateWrapper<PoolTable> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(tableParam.getState() != null, PoolTable::getState,tableParam.getState());
        wrapper.set(PoolTable::getStartTime, new Timestamp(System.currentTimeMillis()));
        wrapper.eq(CheckUtil.assertNotEmpty(tableParam.getTableId(),"更新的tableId为空"),PoolTable::getTableId,tableParam.getTableId());
        try {
            return tableMapper.update(wrapper);
        } catch (Exception e) {
            throw new ServiceException(TableError.START_ERROR,e.getMessage());
        }
    }

    @Override
    public Integer stop(TableParam tableParam) {
        // update pool_table set state = ?,start_time = null where table_id = ?
        LambdaUpdateWrapper<PoolTable> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(tableParam.getState() != null, PoolTable::getState,tableParam.getState());
        wrapper.set(PoolTable::getStartTime,null);
        wrapper.eq(CheckUtil.assertNotEmpty(tableParam.getTableId(),"更新的tableId为空"),PoolTable::getTableId,tableParam.getTableId());
        try {
            return tableMapper.update(wrapper);
        } catch (Exception e) {
            throw new ServiceException(TableError.STOP_ERROR,e.getMessage());
        }
    }
}
